

using System;
using System.Linq;
using System.Linq.Dynamic.Core;
using Abp.Linq.Extensions;
using System.Collections.Generic;
using System.Threading.Tasks;
using Abp.Domain.Repositories;
using Dyan.PlatformSystem.Customers.Exporting;
using Dyan.PlatformSystem.Customers.Dtos;
using Dyan.PlatformSystem.Dto;
using Abp.Application.Services.Dto;
using Dyan.PlatformSystem.Authorization;
using Abp.Extensions;
using Abp.Authorization;
using Microsoft.EntityFrameworkCore;

namespace Dyan.PlatformSystem.Customers
{
	[AbpAuthorize(AppPermissions.Pages_CustomerBaseInfos)]
    public class CustomerBaseInfosAppService : PlatformSystemAppServiceBase, ICustomerBaseInfosAppAppService
    {
		 private readonly IRepository<CustomerBaseInfo, Guid> _customerBaseInfoRepository;
		 private readonly ICustomerBaseInfosExcelExporter _customerBaseInfosExcelExporter;
		 

		  public CustomerBaseInfosAppService(IRepository<CustomerBaseInfo, Guid> customerBaseInfoRepository, ICustomerBaseInfosExcelExporter customerBaseInfosExcelExporter ) 
		  {
			_customerBaseInfoRepository = customerBaseInfoRepository;
			_customerBaseInfosExcelExporter = customerBaseInfosExcelExporter;
			
		  }

		 public async Task<PagedResultDto<GetCustomerBaseInfoForViewDto>> GetAll(GetAllCustomerBaseInfosInput input)
         {
			
			var filteredCustomerBaseInfos = _customerBaseInfoRepository.GetAll()
						.WhereIf(!string.IsNullOrWhiteSpace(input.Filter), e => false  || e.Name.Contains(input.Filter) || e.PhoneNum.Contains(input.Filter) || e.Email.Contains(input.Filter) || e.Company.Contains(input.Filter) || e.Address.Contains(input.Filter) || e.Sex.Contains(input.Filter))
						.WhereIf(!string.IsNullOrWhiteSpace(input.NameFilter),  e => e.Name.ToLower() == input.NameFilter.ToLower().Trim())
						.WhereIf(!string.IsNullOrWhiteSpace(input.PhoneNumFilter),  e => e.PhoneNum.ToLower() == input.PhoneNumFilter.ToLower().Trim())
						.WhereIf(!string.IsNullOrWhiteSpace(input.EmailFilter),  e => e.Email.ToLower() == input.EmailFilter.ToLower().Trim())
						.WhereIf(!string.IsNullOrWhiteSpace(input.CompanyFilter),  e => e.Company.ToLower() == input.CompanyFilter.ToLower().Trim())
						.WhereIf(!string.IsNullOrWhiteSpace(input.AddressFilter),  e => e.Address.ToLower() == input.AddressFilter.ToLower().Trim())
						.WhereIf(!string.IsNullOrWhiteSpace(input.SexFilter),  e => e.Sex.ToLower() == input.SexFilter.ToLower().Trim())
						.WhereIf(input.MinAgeFilter != null, e => e.Age >= input.MinAgeFilter)
						.WhereIf(input.MaxAgeFilter != null, e => e.Age <= input.MaxAgeFilter);

			var pagedAndFilteredCustomerBaseInfos = filteredCustomerBaseInfos
                .OrderBy(input.Sorting ?? "id asc")
                .PageBy(input);

			var customerBaseInfos = from o in pagedAndFilteredCustomerBaseInfos
                         select new GetCustomerBaseInfoForViewDto() {
							CustomerBaseInfo = new CustomerBaseInfoDto
							{
                                Name = o.Name,
                                PhoneNum = o.PhoneNum,
                                Email = o.Email,
                                Company = o.Company,
                                Address = o.Address,
                                Sex = o.Sex,
                                Age = o.Age,
                                Id = o.Id
							}
						};

            var totalCount = await filteredCustomerBaseInfos.CountAsync();

            return new PagedResultDto<GetCustomerBaseInfoForViewDto>(
                totalCount,
                await customerBaseInfos.ToListAsync()
            );
         }
		 
		 public async Task<GetCustomerBaseInfoForViewDto> GetCustomerBaseInfoForView(Guid id)
         {
            var customerBaseInfo = await _customerBaseInfoRepository.GetAsync(id);

            var output = new GetCustomerBaseInfoForViewDto { CustomerBaseInfo = ObjectMapper.Map<CustomerBaseInfoDto>(customerBaseInfo) };
			
            return output;
         }
		 
		 [AbpAuthorize(AppPermissions.Pages_CustomerBaseInfos_Edit)]
		 public async Task<GetCustomerBaseInfoForEditOutput> GetCustomerBaseInfoForEdit(EntityDto<Guid> input)
         {
            var customerBaseInfo = await _customerBaseInfoRepository.FirstOrDefaultAsync(input.Id);
           
		    var output = new GetCustomerBaseInfoForEditOutput {CustomerBaseInfo = ObjectMapper.Map<CreateOrEditCustomerBaseInfoDto>(customerBaseInfo)};
			
            return output;
         }

		 public async Task CreateOrEdit(CreateOrEditCustomerBaseInfoDto input)
         {
            if(input.Id == null){
				await Create(input);
			}
			else{
				await Update(input);
			}
         }

		 [AbpAuthorize(AppPermissions.Pages_CustomerBaseInfos_Create)]
		 protected virtual async Task Create(CreateOrEditCustomerBaseInfoDto input)
         {
            var customerBaseInfo = ObjectMapper.Map<CustomerBaseInfo>(input);

			
			if (AbpSession.TenantId != null)
			{
				customerBaseInfo.TenantId = (int) AbpSession.TenantId;
			}
		

            await _customerBaseInfoRepository.InsertAsync(customerBaseInfo);
         }

		 [AbpAuthorize(AppPermissions.Pages_CustomerBaseInfos_Edit)]
		 protected virtual async Task Update(CreateOrEditCustomerBaseInfoDto input)
         {
            var customerBaseInfo = await _customerBaseInfoRepository.FirstOrDefaultAsync((Guid)input.Id);
             ObjectMapper.Map(input, customerBaseInfo);
         }

		 [AbpAuthorize(AppPermissions.Pages_CustomerBaseInfos_Delete)]
         public async Task Delete(EntityDto<Guid> input)
         {
            await _customerBaseInfoRepository.DeleteAsync(input.Id);
         } 

		public async Task<FileDto> GetCustomerBaseInfosToExcel(GetAllCustomerBaseInfosForExcelInput input)
         {
			
			var filteredCustomerBaseInfos = _customerBaseInfoRepository.GetAll()
						.WhereIf(!string.IsNullOrWhiteSpace(input.Filter), e => false  || e.Name.Contains(input.Filter) || e.PhoneNum.Contains(input.Filter) || e.Email.Contains(input.Filter) || e.Company.Contains(input.Filter) || e.Address.Contains(input.Filter) || e.Sex.Contains(input.Filter))
						.WhereIf(!string.IsNullOrWhiteSpace(input.NameFilter),  e => e.Name.ToLower() == input.NameFilter.ToLower().Trim())
						.WhereIf(!string.IsNullOrWhiteSpace(input.PhoneNumFilter),  e => e.PhoneNum.ToLower() == input.PhoneNumFilter.ToLower().Trim())
						.WhereIf(!string.IsNullOrWhiteSpace(input.EmailFilter),  e => e.Email.ToLower() == input.EmailFilter.ToLower().Trim())
						.WhereIf(!string.IsNullOrWhiteSpace(input.CompanyFilter),  e => e.Company.ToLower() == input.CompanyFilter.ToLower().Trim())
						.WhereIf(!string.IsNullOrWhiteSpace(input.AddressFilter),  e => e.Address.ToLower() == input.AddressFilter.ToLower().Trim())
						.WhereIf(!string.IsNullOrWhiteSpace(input.SexFilter),  e => e.Sex.ToLower() == input.SexFilter.ToLower().Trim())
						.WhereIf(input.MinAgeFilter != null, e => e.Age >= input.MinAgeFilter)
						.WhereIf(input.MaxAgeFilter != null, e => e.Age <= input.MaxAgeFilter);

			var query = (from o in filteredCustomerBaseInfos
                         select new GetCustomerBaseInfoForViewDto() { 
							CustomerBaseInfo = new CustomerBaseInfoDto
							{
                                Name = o.Name,
                                PhoneNum = o.PhoneNum,
                                Email = o.Email,
                                Company = o.Company,
                                Address = o.Address,
                                Sex = o.Sex,
                                Age = o.Age,
                                Id = o.Id
							}
						 });


            var customerBaseInfoListDtos = await query.ToListAsync();

            return _customerBaseInfosExcelExporter.ExportToFile(customerBaseInfoListDtos);
         }


    }
}